package com.caishi.lkx.common.fliter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSONObject;
import com.caishi.lkx.common.Jwt;
import com.caishi.lkx.common.context.Context;
import com.caishi.lkx.common.context.RequireContext;
import com.caishi.lkx.common.context.Role;
import com.caishi.lkx.common.ienum.DeviceType;
import com.caishi.lkx.common.util.HttpContextUtil;
import com.caishi.lkx.user.ienum.type.UserType;
import com.zzw.common.util.HttpWebUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;

/**
 * @author by keray
 * date:2021/4/1 10:49 上午
 */
@Slf4j
@Component
public class ContextInterceptor implements HandlerInterceptor {

    public static final AES AES = new AES("05ee4559b3db2ab9a1f5d86a316c90d4".getBytes(StandardCharsets.UTF_8));
    private static final AntPathMatcher pathMatcher = new AntPathMatcher();

    @Autowired
    @Qualifier("customContext")
    private Context context;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //log.info("进入平台id校验拦截，{}",HttpContextUtil.currentDeviceType(request));
        // 判断 handler 是否为 HandlerMethod

            if (handler instanceof HandlerMethod handlerMethod) {
                //log.info("请求url,{}",request.getRequestURI());
                // 获取方法上的注解
                Annotation[] annotations = handlerMethod.getMethod().getAnnotations();
                for (Annotation annotation : annotations) {
                    //log.info("注解,{}",annotation.getClass().getName());
                    if (annotation instanceof RequireContext) {
                        // 执行 context 设置逻辑
                        Long groupId = getGid(request, ((RequireContext) annotation).value());
                        context.setGroupId(groupId);
                    }
                }
            }
        return true; // 放行请求
    }


    public  Long getGid(HttpServletRequest request, Role[] roles) throws Exception {

        if(Arrays.stream(roles).anyMatch(role -> (role == Role.APP || role == Role.PC )) && HttpContextUtil.currentDeviceType(request) != DeviceType.admin){
            String aesStr = request.getHeader(TokenFilter.TOKEN_USER_GROUP);
            log.info("getGid:{}", aesStr);
            if (aesStr == null) {
                throw new IOException("平台id不能为空");
            }
            aesStr = AES.decryptStr(aesStr);
            return Long.parseLong(aesStr);
        }
        if(Arrays.stream(roles).anyMatch(role -> role == Role.CHANNEL) && HttpContextUtil.currentDeviceType(request) == DeviceType.admin){
            String token = HttpWebUtil.getCookieValue(request, TokenFilter.ADMIN_TOKEN);
            JSONObject tokenResult;
            if (StrUtil.isNotBlank(token)) {
                    tokenResult = new JSONObject();
                    tokenResult.putAll(Jwt.validToken(token));
                    // 校验token是否过期
                    if (tokenExpireCheck(tokenResult)) {
                       throw new Exception("登录失效");
                    }
                    if(tokenResult.get(TokenFilter.TOKEN_USER_TYPE_KEY).equals(UserType.channelBusiness.name())){
                        return (Long) tokenResult.get(TokenFilter.TOKEN_USER_GROUP);
                    }
            }
        }
        return null;

    }

    private boolean tokenExpireCheck(Map<String, Object> tokenResult) {

        if (tokenResult.get(TokenFilter.TOKEN_TIME_KEY) != null) {
            var time = Long.parseLong(tokenResult.get(TokenFilter.TOKEN_TIME_KEY).toString());
            return System.currentTimeMillis() - time > (long) TokenFilter.TOKEN_EXPIRE_DAYS * 24 * 60 * 60 * 1000;
        }
        return false;
    }
    public String decrypt(String str){
        return AES.decryptStr(str);
    }

}
